Option Explicit

'################################################################
' Descriptor
' 表描述符，用来描述 table_references
' 包括 From，join 等
'################################################################

Implements IFromItem
Implements ISubSelectContainer

'################################################################
' Field
'################################################################
' 当前表的筛选类型
Private fieldFromItemType As SqlEnum_FromItemType
' 当前表的别名
Private tableAlias As String
' sql 中的表定义
Private fieldSqlTableDefine As ISqlTableDefine
' 表的筛选条件
Private fieldConditions As Collection

'################################################################
' Constructor
'################################################################
Private Sub Class_Initialize()
    Set fieldConditions = new Collection
End Sub

Private Sub Class_Terminate()
    Set fieldSqlTableDefine = Nothing
    Set fieldConditions = Nothing
End Sub

'################################################################
' Init
'################################################################
' 初始化一个真实表的表定义
' @param fromItemTypeVal 当前表的筛选类型
' @param tableAliasVal 当前表的别名
' @param tableNameVal 当前的表名
Public Sub InitForReal(ByRef fromItemTypeVal As SqlEnum_FromItemType, _
    ByRef tableAliasVal As String, ByRef tableNameVal As String)
    ' 设置 当前表的筛选类型
    fieldFromItemType = fromItemTypeVal
    ' 设置 当前表的别名
    ' 如果没有别名，则直接使用真实表的名称
    ' 如: select * from tableA  <<< 这里不存在表的别名
    If tableAliasVal = "" Then
        tableAlias = tableNameVal
    Else
        tableAlias = tableAliasVal
    End If

    ' 设置 表定义
    Dim tempSqlTableDefine As RealNameSqlTableDefine
    Set tempSqlTableDefine = New RealNameSqlTableDefine
    tempSqlTableDefine.Init tableNameVal
    Set fieldSqlTableDefine = tempSqlTableDefine
End Sub

' 初始化一个子查询的表定义
' @param fromItemTypeVal 当前表的筛选类型
' @param tableAliasVal 当前表的别名
' @param sqlTable 一个实现了 ISqlTableDefine 接口的查询或者 Join
Public Sub InitForSub(ByRef fromItemTypeVal As SqlEnum_FromItemType, _
    ByRef tableAliasVal As String, ByRef sqlTable As ISqlTableDefine)
    ' 设置 当前表的筛选类型
    fieldFromItemType = fromItemTypeVal
    ' 设置 当前表的别名
    ' 如: select * from (select * from tableA)  <<< 这里不存在表的别名
    If tableAliasVal = "" Then
        tableAlias = sqlTable.getTableName
    Else
        tableAlias = tableAliasVal
    End If

    ' 将子查询作为表定义
    Set fieldSqlTableDefine = sqlTable
End Sub

'################################################################
' Implements IFromItem
'################################################################
' 当前数据源表的数据取得方式
Public Property Get IFromItem_FromType() As SqlEnum_FromItemType
    IFromItem_FromType = fieldFromItemType
End Property

' 当前数据源表的别名
Public Property Get IFromItem_Alias() As String
    IFromItem_Alias = tableAlias
End Property

' 当前数据源表的真名
' 如果没有需要生成一个临时表名
Public Property Get IFromItem_Name() As String
    IFromItem_Name = fieldSqlTableDefine.getTableName
End Property

' sql 中的表定义
' @return ISqlTableDefine
Public Property Get IFromItem_SqlTableDefine() As ISqlTableDefine
    Set IFromItem_SqlTableDefine = fieldSqlTableDefine
End Property

' 表的筛选条件
' @return List<SqlCondition>
Public Property Get IFromItem_Conditions() As Collection
    Set IFromItem_Conditions = fieldConditions
End Property

' 添加筛选条件
Public Sub IFromItem_addCondition(ByRef condition As SqlCondition)
    Me.addCondition condition
End Sub

'################################################################
' Implements ISubSelectContainer
'################################################################
Public Function ISubSelectContainer_hasSubSelect() As Boolean
    ' 1. 检查表是否是子查询
    If TypeOf fieldSqlTableDefine Is SelectSql Then
        ISubSelectContainer_hasSubSelect = True
        Exit Function
    End If

    ' 2. 检查条件中是否存在子查询
    If fieldConditions.Count <> 0 Then
        Dim sc As ISubSelectContainer
        For Each sc in fieldConditions
            If sc.hasSubSelect Then
                ISubSelectContainer_hasSubSelect = True
                Exit Function
            End If
        Next
    End If

    ISubSelectContainer_hasSubSelect = False
End Function

' 获取当前组件中的子查询对象
' 获取子查询对象的优先级
' 表定义是子查询 > 条件中包含的子查询
' @return List<SelectSql>
Public Function ISubSelectContainer_getSubSelects() As Collection
    Dim result as Collection
    Set result = new Collection

    ' 1. 检查表是否是子查询
    If TypeOf fieldSqlTableDefine Is SelectSql Then
        result.Add fieldSqlTableDefine
    End If

    ' 2. 检查条件中是否存在子查询
    If fieldConditions.Count <> 0 Then
        Dim sc As ISubSelectContainer
        For Each sc in fieldConditions
            If sc.hasSubSelect Then
                UtilsCollection.addAllCollection result, sc.getSubSelects
            End If
        Next
    End If

    Set ISubSelectContainer_getSubSelects = result
End Function

'################################################################
' Function
'################################################################
' 添加筛选条件
Public Sub addCondition(ByRef condition As SqlCondition)
    fieldConditions.Add condition
End Sub